#include "SoundCapture.h"
#include <vector>
#include <rtptimeutilities.h>

using namespace ipsound;

SoundCapture::SoundCapture( MutexBuffer* buffer, LPDIRECTSOUNDCAPTUREBUFFER8 captureBuf8 )
:buffer( buffer )
,captureBuf8( captureBuf8 )
,soundBufOffset( 0 )
,soundBufSize( 0 )
,notifySamplesNum( 4 )
{
	captureBuf8->GetFormat( &wfx, sizeof(WAVEFORMATEX), 0 );

	DSCBCAPS caps = {0};
	caps.dwSize = sizeof(DSCBCAPS);
	captureBuf8->GetCaps( &caps );
	soundBufSize = caps.dwBufferBytes;

	//file = fopen("c:\\sample.wav","rb");
}

void* SoundCapture::Thread()
{
	LPDIRECTSOUNDNOTIFY8 notify = 0;
	HANDLE bufEvent = CreateEvent( 0, false, false, 0);
	
	std::vector<DSBPOSITIONNOTIFY> notifyPos( notifySamplesNum );

	captureBuf8->QueryInterface(IID_IDirectSoundNotify, (void**)&notify);

	for(int i = 0; i != notifySamplesNum; ++i)
	{
		notifyPos[i].dwOffset = (soundBufSize * (i + 1) / notifySamplesNum) - 1;
		notifyPos[i].hEventNotify = bufEvent;
	}

	notify->SetNotificationPositions( notifySamplesNum, &notifyPos[0] );
	notify->Release();

	captureBuf8->Start( DSCBSTART_LOOPING );
	ThreadStarted();

	while( /*!feof(file)*/true )
	{		
		HRESULT result = WaitForSingleObject( bufEvent, INFINITE );

		//RTPTime::Wait(0.5);

		GetDataFromSoundBuffer();
	}

	CloseHandle( bufEvent );

	return 0;
}

void SoundCapture::SetNotifySamplesNum( const unsigned short& notifySamplesNum )
{
	this->notifySamplesNum = notifySamplesNum;
}

SoundCapture::~SoundCapture()
{
	fclose(file);
}

void SoundCapture::GetDataFromSoundBuffer()
{
	void* captureData = 0;
	unsigned long captureLength = 0;
	void* captureData2 = 0;
	unsigned long captureLength2 = 0;
	void* playData = NULL;
	unsigned int  dataWrote = 0;
	unsigned long readPos = 0;

	/*captureLength = 8000;
	captureData = malloc(captureLength);
	size_t read = fread(captureData,1,captureLength,file);*/

	captureBuf8->GetCurrentPosition( 0, &readPos);

	long lockSize = readPos - soundBufOffset;
	if( lockSize < 0 )
	  lockSize += soundBufSize;

	captureBuf8->Lock( soundBufOffset, lockSize, &captureData, &captureLength, &captureData2, &captureLength2, 0L );
	buffer->Write( captureData, /*read*/captureLength );

	if ( captureData2 )
		buffer->Write( captureData2, captureLength2 );

	captureBuf8->Unlock(captureData, captureLength, captureData2, captureLength2);

	//free(captureLength);

	soundBufOffset += captureLength; 
	soundBufOffset %= soundBufSize; 
	soundBufOffset += captureLength2; 
	soundBufOffset %= soundBufSize;
}
